package com.hrsoft.edi.stub.internal;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import com.qimen.api.QimenResponse;
import com.qimencloud.api.QimenCloudResponse;
import com.taobao.api.ApiException;
import com.taobao.api.TaobaoResponse;
import com.taobao.api.internal.mapping.*;
import com.taobao.api.internal.util.StringUtils;

public class Converters
{
    public static boolean isCheckJsonType = false;
    private static final Object emptyCache = new Object();
    private static final Map<String, Set<String>> baseProps = new HashMap();
    private static final Map<String, Object> fieldCache = new ConcurrentHashMap();
    private static final Map<String, Object> methodCache = new ConcurrentHashMap();

    private Converters() {
    }

    public static <T> T convert(Class<T> clazz, Reader reader, String responseType) throws ApiException
    {
        T rsp = null;

        try {
            rsp = clazz.newInstance();
            Field successField = null;
            Field[] successFields = clazz.getDeclaredFields();
            if (successFields != null && successFields.length > 0) {
                Field[] arr$ = successFields;
                int len$ = successFields.length;

                for(int i$ = 0; i$ < len$; ++i$) {
                    Field field = arr$[i$];
                    if (field.getName().equals("success")) {
                        successField = field;
                    }
                }
            }

            Method successMethod = null;
            Method[] methods = clazz.getMethods();
            if (methods != null && methods.length > 0) {
                Method[] arr$ = methods;
                int len$ = methods.length;

                for(int i$ = 0; i$ < len$; ++i$) {
                    Method method = arr$[i$];
                    if (method.getName().equals("setSuccess")) {
                        successMethod = method;
                    }
                }
            }

            if (successField != null && successMethod != null) {
                String successItemName = successField.getName();
                String successListName = null;
                ApiField jsonField = (ApiField)successField.getAnnotation(ApiField.class);
                if (jsonField != null) {
                    successItemName = jsonField.value();
                }

                ApiListField jsonListField = (ApiListField)successField.getAnnotation(ApiListField.class);
                if (jsonListField != null) {
                    successListName = jsonListField.value();
                }

                if (!reader.hasReturnField(successItemName) && successListName != null && !reader.hasReturnField(successListName)) {
                }

                setMethodValue(rsp, reader, successItemName, successListName, successField, successMethod);
            }

            BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
            PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
            PropertyDescriptor[] arr$ = pds;
            int len$ = pds.length;

            for(int i$ = 0; i$ < len$; ++i$) {
                PropertyDescriptor pd = arr$[i$];
                Method method = getCacheMethod(clazz, pd);
                if (method != null) {
                    String itemName = pd.getName();
                    String listName = null;
                    Field field = null;
                    boolean isErrorParam = false;
                    if ((TaobaoResponse.class.isAssignableFrom(clazz) || QimenCloudResponse.class.isAssignableFrom(clazz) || QimenResponse.class.isAssignableFrom(clazz)) && clazz.getSuperclass().getName().equals("java.lang.Object")) {
                        isErrorParam = true;
                        field = getField(clazz, pd);
                    } else {
                        Set<String> stopProps = (Set)baseProps.get(clazz.getSuperclass().getName());
                        if (stopProps != null && stopProps.contains(itemName)) {
                            isErrorParam = true;
                            field = getField(clazz.getSuperclass(), pd);
                        } else {
                            field = getField(clazz, pd);
                        }
                    }

                    if (field != null) {
                        if (isErrorParam) {
                            if (null != responseType && !"top".equals(responseType)) {
                                if (!"qimen1".equals(responseType) && !"qimen2".equals(responseType)) {
                                    if ("dingtalk".equals(responseType)) {
                                        DingTalkErrorField
                                            jsonField = (DingTalkErrorField)field.getAnnotation(DingTalkErrorField.class);
                                        if (jsonField != null) {
                                            itemName = jsonField.value();
                                            setMethodValue(rsp, reader, itemName, listName, field, method);
                                        }
                                    }
                                } else {
                                    QimenErrorField jsonField = (QimenErrorField)field.getAnnotation(QimenErrorField.class);
                                    if (jsonField != null) {
                                        itemName = jsonField.value();
                                        setMethodValue(rsp, reader, itemName, listName, field, method);
                                    }
                                }
                            } else {
                                TopErrorField jsonField = (TopErrorField)field.getAnnotation(TopErrorField.class);
                                if (jsonField != null) {
                                    itemName = jsonField.value();
                                    setMethodValue(rsp, reader, itemName, listName, field, method);
                                }
                            }
                        } else {
                            ApiField jsonField = (ApiField)field.getAnnotation(ApiField.class);
                            if (jsonField != null) {
                                itemName = jsonField.value();
                            }

                            ApiListField jsonListField = (ApiListField)field.getAnnotation(ApiListField.class);
                            if (jsonListField != null) {
                                listName = jsonListField.value();
                            }

                            ApiListItem ApiListItem = (ApiListItem)field.getAnnotation(ApiListItem.class);
                            if (ApiListItem != null) {
                                listName = ApiListItem.rootName();
                                itemName = ApiListItem.value();
                            }

                            if (reader.hasReturnField(itemName) || listName != null && reader.hasReturnField(listName)) {
                                setMethodValue(rsp, reader, itemName, listName, field, method);
                            }
                        }
                    }
                }
            }

            return rsp;
        } catch (Exception var21) {
            throw new ApiException(var21);
        }
    }

    public static Field getField(Class<?> clazz, PropertyDescriptor pd) throws Exception {
        String key = clazz.getName() + "_" + pd.getName();
        Object field = fieldCache.get(key);
        if (field == null) {
            try {
                field = clazz.getDeclaredField(pd.getName());
            } catch (NoSuchFieldException var8) {
                Class<?> superClazz = clazz.getSuperclass();
                if (!superClazz.getName().equals("java.lang.Object")) {
                    try {
                        field = superClazz.getDeclaredField(pd.getName());
                    } catch (NoSuchFieldException var7) {
                        field = emptyCache;
                    }
                } else {
                    field = emptyCache;
                }
            }

            fieldCache.put(key, field);
        }

        return field == emptyCache ? null : (Field)field;
    }

    private static Method getCacheMethod(Class<?> clazz, PropertyDescriptor pd) {
        String key = clazz.getName() + "_" + pd.getName();
        Object method = methodCache.get(key);
        if (method == null) {
            method = pd.getWriteMethod();
            if (method == null) {
                method = emptyCache;
            }

            methodCache.put(key, method);
        }

        return method == emptyCache ? null : (Method)method;
    }

    private static <T> void setMethodValue(T rsp, Reader reader, String itemName, String listName, Field field, Method method) throws Exception {
        Class<?> typeClass = field.getType();
        Object value;
        if (String.class.isAssignableFrom(typeClass)) {
            value = reader.getPrimitiveObject(itemName);
            if (value instanceof String) {
                method.invoke(rsp, value.toString());
            } else {
                if (isCheckJsonType && value != null) {
                    throw new ApiException(itemName + " is not a String");
                }

                if (value != null) {
                    method.invoke(rsp, value.toString());
                } else {
                    method.invoke(rsp, "");
                }
            }
        } else if (Long.class.isAssignableFrom(typeClass)) {
            value = reader.getPrimitiveObject(itemName);
            if (value instanceof Long) {
                method.invoke(rsp, (Long)value);
            } else {
                if (isCheckJsonType && value != null) {
                    throw new ApiException(itemName + " is not a Number(Long)");
                }

                if (StringUtils.isNumeric(value)) {
                    method.invoke(rsp, Long.valueOf(value.toString()));
                }
            }
        } else if (Boolean.class.isAssignableFrom(typeClass)) {
            value = reader.getPrimitiveObject(itemName);
            if (value instanceof Boolean) {
                method.invoke(rsp, (Boolean)value);
            } else {
                if (isCheckJsonType && value != null) {
                    throw new ApiException(itemName + " is not a Boolean");
                }

                if (value != null) {
                    method.invoke(rsp, Boolean.valueOf(value.toString()));
                }
            }
        } else if (Date.class.isAssignableFrom(typeClass)) {
            value = reader.getPrimitiveObject(itemName);
            if (value instanceof String) {
                method.invoke(rsp, StringUtils.parseDateTime(value.toString()));
            } else if (value instanceof Long) {
                method.invoke(rsp, new Date((Long)value));
            }
        } else if (List.class.isAssignableFrom(typeClass)) {
            Type fieldType = field.getGenericType();
            if (fieldType instanceof ParameterizedType) {
                ParameterizedType paramType = (ParameterizedType)fieldType;
                Type[] genericTypes = paramType.getActualTypeArguments();
                if (genericTypes != null && genericTypes.length > 0 && genericTypes[0] instanceof Class) {
                    Class<?> subType = (Class)genericTypes[0];
                    List<?> listObjs = reader.getListObjects(listName, itemName, subType);
                    if (listObjs != null) {
                        method.invoke(rsp, listObjs);
                    }
                }
            }
        } else if (Integer.class.isAssignableFrom(typeClass)) {
            value = reader.getPrimitiveObject(itemName);
            if (value instanceof Integer) {
                method.invoke(rsp, (Integer)value);
            } else {
                if (isCheckJsonType && value != null) {
                    throw new ApiException(itemName + " is not a Number(Integer)");
                }

                if (StringUtils.isNumeric(value)) {
                    method.invoke(rsp, Integer.valueOf(value.toString()));
                }
            }
        } else if (Double.class.isAssignableFrom(typeClass)) {
            value = reader.getPrimitiveObject(itemName);
            if (value instanceof Double) {
                method.invoke(rsp, (Double)value);
            } else if (isCheckJsonType && value != null) {
                throw new ApiException(itemName + " is not a Double");
            }
        } else if (Number.class.isAssignableFrom(typeClass)) {
            value = reader.getPrimitiveObject(itemName);
            if (value instanceof Number) {
                method.invoke(rsp, (Number)value);
            } else if (isCheckJsonType && value != null) {
                throw new ApiException(itemName + " is not a Number");
            }
        } else {
            value = reader.getObject(itemName, typeClass);
            if (value != null) {
                method.invoke(rsp, value);
            }
        }

    }

    static {
        baseProps.put(TaobaoResponse.class.getName(), StringUtils.getClassProperties(TaobaoResponse.class, false));
        baseProps.put(QimenResponse.class.getName(), StringUtils.getClassProperties(QimenResponse.class, false));
    }
}
